package NLP;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import sentStruct.Verb;
import edu.stanford.nlp.ling.CoreAnnotations.PartOfSpeechAnnotation;
import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.ling.IndexedWord;
import edu.stanford.nlp.trees.semgraph.SemanticGraph;
import edu.stanford.nlp.trees.semgraph.SemanticGraphEdge;

public class SemanticGraphHandler {
	
	//subjects relations
	public static final String nominalSubject = "nsubj";
	public static final String controllingSubject = "xsubj";
	public static final String passiveNominalSubject ="nsubjpass";
	//object relations
	public static final String directObject = "dobj";
	public static final String indirectObject = "iobj ";
	//preposition relations
	public static final String prepositionObject = "pobject";
	public static final String preposition = "prep";
	//adjective relations
	public static final String adjectivalModifier = "amod";
	//adverb relation
	public static final String adverbialModifier = "advmod";
	
	private SemanticGraph graph;
	
	public SemanticGraphHandler(SemanticGraph graph) {
		super();
		this.graph = graph;
	}
	
	

	public SemanticGraph getGraph() {
		return graph;
	}

	public void setGraph(SemanticGraph graph) {
		this.graph = graph;
	}




	public Set<SemanticGraphEdge> getEdgesFromRelation(String rel) {
		Set<SemanticGraphEdge> edges = graph.getEdgeSet();
		Set<SemanticGraphEdge> resultEdges = new HashSet<SemanticGraphEdge>();
		for (SemanticGraphEdge edge : edges) {
			if (edge.getRelation().toString().equals(rel))
				resultEdges.add(edge);
				
			
			
		}
		return resultEdges;

}





	public boolean isSubject(CoreLabel token) {
		boolean test = false;
		IndexedWord indWord=null;
        try {
        indWord=  graph.getNodeByIndex(token.index());
        List<SemanticGraphEdge> incomingEdges = graph.incomingEdgeList(indWord); 
        for (SemanticGraphEdge edge : incomingEdges){
        	if (edge.getRelation().toString().equals(nominalSubject)||
        			edge.getRelation().toString().equals(controllingSubject)||
        			edge.getRelation().toString().equals(passiveNominalSubject))
        		test= true;
        		
        }
        

        }
        catch (IllegalArgumentException e) {
        }
		return test;
	}



	public boolean isVerb(CoreLabel token) {
		PartOfSpeechAnalyser posAn = new PartOfSpeechAnalyser();
		if (posAn.stringToClass(token.get(PartOfSpeechAnnotation.class)).equals(Verb.class))
		return true;
		else return false;
	}



	public boolean isObject(CoreLabel token) {
		boolean test = false;
		IndexedWord vertex = getVertex(token);
		PartOfSpeechAnalyser posAn = new PartOfSpeechAnalyser();
		if (vertex==null)
			return false;
		 List<SemanticGraphEdge> incomingEdges = graph.incomingEdgeList(vertex); 
	        for (SemanticGraphEdge edge : incomingEdges){
	        	if (edge.getRelation().toString().equals(directObject)||
	        			edge.getRelation().toString().equals(indirectObject))
	        		test= true;
	        		
	        }
	        List<SemanticGraphEdge> outgoingEdges = graph.outgoingEdgeList(vertex); 
	        for (SemanticGraphEdge edge : outgoingEdges){
	        	if (edge.getRelation().toString().equals(nominalSubject)&&
	        			posAn.isNoun(edge.getSource().get(PartOfSpeechAnnotation.class)))
	        		test= true;
	        		
	        }
		
		return test;
	}



	public boolean isPrepositionObject(CoreLabel token) {
		boolean test = false;
		IndexedWord vertex = getVertex(token);
		if (vertex==null)
			return false;
	    List<SemanticGraphEdge> edges = graph.incomingEdgeList(vertex);
	    for (SemanticGraphEdge edge : edges){
	    	if (edge.getRelation().toString().contains(preposition)||
	    			edge.getRelation().toString().equals(prepositionObject))
	    		test = true;
	    }
		return test;
	}



	public List<CoreLabel> getAdverbsFromVerb(CoreLabel token) {
		List<CoreLabel> adverbs = new ArrayList<CoreLabel>();
		IndexedWord vertex = getVertex(token);
        List<SemanticGraphEdge> outgoingEdges = graph.outgoingEdgeList(vertex); 
        for (SemanticGraphEdge edge : outgoingEdges)
        	if (edge.getRelation().toString().equals(adverbialModifier)){
        		
        		adverbs.add(edge.getTarget());
        	}
        	 
        	
        
        

		return adverbs;
	}



	public List<CoreLabel> getAdjectivesFromNoun(CoreLabel token) {
		List<CoreLabel> adjectives = new ArrayList<CoreLabel>();
		PartOfSpeechAnalyser posAn = new PartOfSpeechAnalyser();
		IndexedWord vertex = getVertex(token);
        List<SemanticGraphEdge> outgoingEdges = graph.outgoingEdgeList(vertex); 
        for (SemanticGraphEdge edge : outgoingEdges)
        	if (edge.getRelation().toString().equals(adjectivalModifier))
        		adjectives.add(edge.getTarget());
        List<SemanticGraphEdge> incomingEnges = graph.incomingEdgeList(vertex);
        for (SemanticGraphEdge edge : incomingEnges)
        	if (edge.getRelation().toString().equals(nominalSubject)&&posAn.isAdjective(edge.getSource().get(PartOfSpeechAnnotation.class)))
        		adjectives.add(edge.getSource());
        
        

		
		return adjectives;
	}



	public String getStringPrepotistionFromNoun(CoreLabel token) {
		String prepString = null;
		IndexedWord vertex = getVertex(token);
		if (vertex==null)
			return null;
		List<SemanticGraphEdge> edges = graph.incomingEdgeList(vertex);
		for (SemanticGraphEdge edge : edges){
			if (edge.getRelation().toString().contains(preposition)){
				if (edge.getRelation().toString().equals(preposition))
					return null;
				
				return edge.getRelation().toString().substring(5,edge.getRelation().toString().length());
			}
			if (edge.getRelation().toString().equals(prepositionObject))
				return edge.getSource().lemma();
		}
		
				

		return prepString;
	}
	
	public IndexedWord getVertex(CoreLabel token){
		IndexedWord indWord = null;
		 try {
		        indWord=  graph.getNodeByIndex(token.index());
		        
		 }
		 catch (IllegalArgumentException e) {
	        }
		 return indWord;
		 
		 
	}
}
